--[[ Copyright 2012, Chris Ho                               ]]--
--[[ MIT License (Please read the LICENSE file for details) ]]--

Use("common/Const");
Use("common/Log");
Use("common/Position");
Use("common/Task");
Use("common/Creature");
Use("common/Pet");
Use("common/Skill");

-- The lancer persona overrides some of the default persona behavior
-- for the lancer's superior survivability. It tries its best to keep
-- the owner alive.
local name = "Lancer";
local Initialize, status = loadfile(PERSONALITY_DEFAULT);
if (Initialize == nil) then
  Alert(name .. ": " .. status);
  return ME;
end

Lancer = {};

--[[ Override Default Rating Calculation ]]--
-- Lancers try to protect the owner above all else. Distance is
-- not a major factor.
function Lancer.RateTarget(self, _id)
  local target = GetV(V_TARGET, _id);
  local pettarget = GetV(V_TARGET, self.id);
  local ownertarget = GetV(V_TARGET, self.owner.id);
  local score = Pet.RateTarget(self, _id);

  -- If he's attacking the owner, give bonus.
  if (target == self.owner.id) then score = score + 8 / self:GetTranquility() end
  -- If he's attacking me, give bonus.
  if (target == self.id) then score = score + 6 / self:GetTranquility() end
  -- If he's my owner's target, give bonus.
  if (ownertarget == _id) then score = score + 4 / self:GetTranquility() end
  -- If he's my current target, give bonus.
  if (pettarget == _id) then score = score + 2 / self:GetTranquility() end

  -- Note: lancers don't consider allies in the score!

  return score;
end

--[[ Determine if a target is a threat ]]--
-- Lancers are more aggressive when considering threats. They consider the
-- master as an extension of themselves.
function Lancer.Consider(self, _id)
  -- Skip our allies in the search.
  if (self:FetchFriend(_id) == nil) then
    -- Check the intended target of the actor.
    local intent = GetV(V_TARGET, _id);
    if ((intent ~= self.id) and (intent ~= self.owner.id)) then
      -- It's not attacking us. Are we attacking it?
      if ((GetV(V_TARGET, self.owner.id) ~= _id) and (GetV(V_TARGET, self.id) ~= _id)) then
        -- The target is of no interest to me nor my master.
        return false;
      end
    end

    -- This actor has targeted an ally, or he is a target of an ally.
    if (IsMonster(_id) == 1) then
      -- Object is a threat (hostile monster).
      return true;
    else
      -- Object is not a monster.
      local motion = GetV(V_MOTION, _id);
      if ((motion == MOTION_ATTACK) or (motion == MOTION_ATTACK2)) then
        -- But the object is still attacking us, which makes it a threat.
        return true;
      end
    end
  end

  -- Not a threat.
  return false;
end

--[[ Lancers are less tranquil than others ]]--
function Lancer.GetTranquility(self)
  local value = TRANQUILITY - 1;
  if (value < 2) then value = 2 end
  return value;
end
--[[ Lancers are more resilient than others ]]--
function Lancer.GetResilience(self)
  local value = RESILIENCE + 1;
  if (value < 3) then value = 3 end
  return value;
end



-- Initialize base personality.
--local instance = Initialize(...);
--local instance = Initialize(arg[1]);
local instance = Initialize();

instance.RateTarget = Lancer.RateTarget;
instance.Consider = Lancer.Consider;
instance.GetTranquility = Lancer.GetTranquility;
instance.GetResilience = Lancer.GetResilience;

Info(name .. " Loaded");
return instance;
